home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / 3dvect37.zip / PMODE.ASM < prev    next >
Assembly Source File  |  1994-06-22  |  74KB  |  2,197 lines

  1. ; PMODE v2.4 raw, DPMI, VCPI, & XMS compliant protected mode header.
  2. ; By Tran (a.k.a. Thomas Pytel).
  3.  
  4.         .386p
  5.  
  6. LOWMIN          = 0             ; minimum free low memory (in K)
  7. EXTMIN          = 0             ; minimum free extended memory (in K)
  8. SELECTORS       = 8             ; extra selectors for allocation
  9. STAKMAIN        = 100h          ; main execution stream stack size (in para)
  10. STAKRMODE       = 10h           ; real mode call stack size (in para)
  11. STAKPMODE       = 20h           ; protected mode call stack size (in para)
  12. MODENESTING     = 8             ; max number of nested mode switches
  13.  
  14. RMODENUM        = (MODENESTING+1) shr 1
  15. PMODENUM        = MODENESTING shr 1
  16. STAKSIZE        = STAKMAIN+(PMODENUM*STAKPMODE)+(RMODENUM*STAKRMODE)
  17.  
  18. .errnz STAKSIZE gt 0fffh        ; error if stack greater than 64k
  19.  
  20. code16  segment para public use16
  21. code16  ends
  22. code32  segment para public use32
  23. code32  ends
  24. codeend segment para stack use32 'stack'
  25. codeend ends
  26.  
  27. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  28. ; Real mode and 16bit code
  29. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  30. code16  segment para public use16
  31.         assume cs:code16, ds:code16
  32.         org 0
  33.  
  34. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  35. ; 16 bit common system data
  36. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  37. errmsg0         db      '386 or better not detected!!!',7,'$'
  38. errmsg1         db      'Not enough low memory!!!',7,'$'
  39. errmsg2         db      'System is already in V86 mode, and no VCPI or DPMI found!!!',7,'$'
  40. errmsg3         db      'Not enough extended memory!!!',7,'$'
  41. errmsg4         db      'Couldn''t enable A20 gate!!!',7,'$'
  42. errmsg5         db      'Extended memory allocation failure. (weird eh???)',7,'$'
  43.  
  44. nullint         db      0cfh            ; IRET instruction
  45. exitrout        dw      exit            ; exit routine, modified if XMS, VCPI
  46.  
  47. savedstakoff    dw      ?               ; current saved stack offset
  48. savedstakseg    dw      ?               ; current saved stack segment
  49.  
  50. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  51. ; 16 bit common system code
  52. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  53. ;═════════════════════════════════════════════════════════════════════════════
  54. intreal:                                ; real mode int, load FS and GS here
  55.         pushf
  56. ;-----------------------------------------------------------------------------
  57. callreal:                               ; real mode call, load FS and GS here
  58.         push cs
  59.         push offset icreald
  60.         mov fs,cs:v86r_fs
  61.         mov gs,cs:v86r_gs
  62.         mov eax,cs:v86r_eax
  63.         mov ecx,cs:v86r_ecx
  64.         mov edx,cs:v86r_edx
  65.         mov ebx,cs:v86r_ebx
  66.         mov esi,cs:v86r_esi
  67.         mov edi,cs:v86r_edi
  68.         mov ebp,cs:v86r_ebp
  69. ;-----------------------------------------------------------------------------
  70. icreal:                                 ; real mode int, call, or IRQ
  71.         db 66h,68h              ; PUSH destination addx
  72. icrealm1        dd      ?       ;
  73. icrealm0        db      ?       ; CLI or STI
  74.         retf
  75. ;-----------------------------------------------------------------------------
  76. icreald:                                ; done with real int or call
  77.         cli
  78.         pushf
  79.         pop cs:v86r_flags
  80.         mov cs:v86r_eax,eax
  81.         mov cs:v86r_ecx,ecx
  82.         mov cs:v86r_edx,edx
  83.         mov cs:v86r_ebx,ebx
  84.         mov cs:v86r_esi,esi
  85.         mov cs:v86r_edi,edi
  86.         mov cs:v86r_ebp,ebp
  87.         mov cs:v86r_ds,ds
  88.         mov cs:v86r_es,es
  89.         mov cs:v86r_fs,fs
  90.         mov cs:v86r_gs,gs
  91. icreald2:
  92.         mov ax,cs
  93.         mov ds,ax
  94. icrealm2        label word              ; return to pmode modifiable to JMP
  95. ;-----------------------------------------------------------------------------
  96.         mov ebx,ds:cp_savedstakoff      ; DPMI return to pmode
  97.         mov dx,ds:dp_savedstaksel
  98.         mov edi,offset dp_int3_d
  99.         mov si,ds:_selcode
  100.         mov cx,dx
  101.         mov ax,ds:_seldata
  102.         jmp ds:d_switchaddx
  103. ;-----------------------------------------------------------------------------
  104. VICREAL1D=(($-(icrealm2+2))shl 8)+0ebh
  105. v_icreal1d:                             ; VCPI return to pmode from safe
  106.         mov edi,offset cp_int3_d
  107. ;-----------------------------------------------------------------------------
  108. ; EDI=offset to jump to in code32
  109. v_switchtopmode:                        ; VCPI switch to pmode
  110.         mov ds:v_ss_dest,edi
  111.         mov esi,offset v_ss_cr3
  112.         add esi,ds:_code16a
  113.         mov ax,0de0ch
  114.         int 67h
  115. ;-----------------------------------------------------------------------------
  116. CICREAL1D=(($-(icrealm2+2))shl 8)+0ebh
  117. c_icreal1d:                             ; custom return to pmode from safe
  118.     mov edi,offset cp_int3_d
  119. ;-----------------------------------------------------------------------------
  120. ; EDI=offset in pmode to jump to
  121. c_retpmode:                             ; reenter 32bit pmode
  122.         lgdt fword ptr c_gdt32addx      ; set up pmode GDT and IDT
  123.     lidt fword ptr c_idt32addx
  124.     mov ds:gdt32task[5],89h     ; set task as not busy
  125.         mov eax,cr0                     ; switch to pmode
  126.         or al,1
  127.         mov cr0,eax
  128.         db 0eah
  129.         dw $+4,20h
  130.         mov ax,30h                      ; load task register
  131.         ltr ax
  132.     jmp c_gotopmode
  133. ;-----------------------------------------------------------------------------
  134. if ($-(icrealm2+2)) gt 127
  135.   err
  136. endif
  137. CICREAL0D=(($-(icrealm2+2))shl 8)+0ebh
  138. c_icreal0d:                             ; return to pmode from normal
  139.         int 0ffh
  140. ;═════════════════════════════════════════════════════════════════════════════
  141. int32:                                  ; real mode INT32: EDX=off
  142.         pushad
  143.         push ds es fs gs
  144.         cli
  145.         mov ax,cs
  146.         mov ds,ax
  147.         mov ds:p_cpmodem0,edx
  148.         mov al,[esp+45]
  149.         shr al,1
  150.         and al,1
  151.         add al,0fah
  152.         mov ds:p_cpmodem1,al
  153.         push savedstakoff
  154.         push savedstakseg
  155.         movzx ebx,ds:nextmodestack
  156.         lea eax,[ebx-STAKPMODE*16]
  157.         mov ds:nextmodestack,ax
  158.         add ebx,ds:realstackbase
  159.         mov savedstakseg,ss
  160. int32m0         label   word            ; jump to pmode, modifiable
  161. ;-----------------------------------------------------------------------------
  162.         sub sp,ds:dp_savelen
  163.         mov savedstakoff,sp
  164.         mov ax,ss                       ; DPMI jump to pmode
  165.         mov es,ax
  166.         mov di,sp
  167.         xor al,al
  168.         call d_saveaddx
  169.         mov ax,ds:_seldata
  170.         mov cx,ax
  171.         mov dx,ax
  172.         mov edi,offset p_cpmode
  173.         mov si,ds:_selcode
  174.         jmp ds:d_switchaddx
  175. ;-----------------------------------------------------------------------------
  176. VINT32=(($-(int32m0+2))shl 8)+0ebh
  177. v_int32:                                ; VCPI call pmode
  178.         push ds:p_cpmodem2
  179.         mov ds:p_cpmodem2,VCPMODED
  180.         mov savedstakoff,sp
  181.         mov edi,offset p_cpmode1
  182.         jmp v_switchtopmode
  183. ;-----------------------------------------------------------------------------
  184. if ($-(int32m0+2)) gt 127
  185.   err
  186. endif
  187. CINT32=(($-(int32m0+2))shl 8)+0ebh
  188. c_int32:                                ; raw/XMS call pmode
  189.         push ds:p_cpmodem2
  190.         mov ds:p_cpmodem2,CCPMODED
  191.         mov savedstakoff,sp
  192.         mov edi,offset p_cpmode1
  193.         jmp c_retpmode
  194. ;═════════════════════════════════════════════════════════════════════════════
  195. int32d0:                                ; DPMI done with pmode call
  196.         mov di,sp
  197.         mov al,1
  198.         call d_saveaddx
  199.         add sp,ds:dp_savelen
  200. ;-----------------------------------------------------------------------------
  201. int32d2:                                ; done from all
  202.         pop savedstakseg
  203.         pop savedstakoff
  204.         add ds:nextmodestack,STAKPMODE*16
  205.         mov bx,ds:v86r_flags
  206.         mov ax,[esp+44]
  207.         and ax,not 8d5h
  208.         and bx,8d5h
  209.         or ax,bx
  210.         mov [esp+44],ax
  211.         pop gs fs es ds
  212.         popad
  213.         iret
  214. ;═════════════════════════════════════════════════════════════════════════════
  215. int32d1:                                ; VCPI done with pmode call
  216.         mov ss,savedstakseg
  217.         pop ds:p_cpmodem2
  218.         jmp int32d2
  219. ;═════════════════════════════════════════════════════════════════════════════
  220. int32d3:                                ; raw/XMS done with pmode call
  221.         mov c_retreal0m0,offset c_sicreal
  222.         mov ax,cs
  223.         mov ds,ax
  224.         movzx esp,savedstakoff
  225.         mov ss,savedstakseg
  226.         pop ds:p_cpmodem2
  227.         jmp int32d2
  228. ;─────────────────────────────────────────────────────────────────────────────
  229. chek_VCPI:                              ; Chek for VCPI
  230.         xor ax,ax
  231.         mov gs,ax
  232.         mov ax,gs:[67h*4]
  233.         or ax,gs:[(67h*4)+2]
  234.         jz short chekVCPIa
  235.         mov ax,0de00h
  236.         int 67h
  237.         or ah,ah
  238.         clc
  239.         jz short chekVCPId
  240. chekVCPIa:
  241.         stc
  242. chekVCPId:
  243.         ret
  244. ;─────────────────────────────────────────────────────────────────────────────
  245. chek_processor:                         ; Detect if current processor 386
  246.         pushf
  247.         xor ah,ah
  248.         push ax
  249.         popf
  250.         pushf
  251.         pop ax
  252.         and ah,0f0h
  253.         cmp ah,0f0h
  254.         je short detectno386
  255.         mov ah,0f0h
  256.         push ax
  257.         popf
  258.         pushf
  259.         pop ax
  260.         and ah,0f0h
  261.         jz short detectno386
  262.         popf
  263.         ret
  264. detectno386:
  265.         mov dx,offset errmsg0
  266.         jmp short exit16err
  267. ;─────────────────────────────────────────────────────────────────────────────
  268. chek_V86:                               ; Chek if already in V86 mode
  269.         smsw ax
  270.         test al,1
  271.         mov dx,offset errmsg2
  272.         jnz short exit16err
  273.         ret
  274. ;─────────────────────────────────────────────────────────────────────────────
  275. pregetlomem:                            ; Get low memory or abort
  276.         add eax,ds:_lomembase
  277.         mov ebx,ds:_lomemtop
  278.         cmp eax,ebx
  279.         ja short pregetlomema
  280.         mov ecx,eax
  281.         xchg eax,ds:_lomembase
  282.         sub ebx,ecx
  283.         cmp ebx,LOWMIN*1024
  284.         jb short pregetlomema
  285.         ret
  286. pregetlomema:
  287.         mov dx,offset errmsg1
  288. ;─────────────────────────────────────────────────────────────────────────────
  289. exit16err:                              ; Exit program with message
  290.         mov ah,9
  291.         int 21h
  292.         jmp exitrout
  293. ;-----------------------------------------------------------------------------
  294. exit:                                   ; Guess what???
  295.         mov ah,4ch
  296.         mov al,ds:_exitcode
  297.         int 21h
  298. ;═════════════════════════════════════════════════════════════════════════════
  299. start16:                                ; Program begins here
  300.         cli
  301.         cld
  302.         push cs
  303.         pop ds
  304.  
  305.         call chek_processor             ; is it at least a 386¿
  306.  
  307.         mov ax,es                       ; set up a bunch of pointers
  308.         movzx eax,ax
  309.         shl eax,4
  310.         mov ds:_pspa,eax
  311.         mov eax,code16
  312.         shl eax,4
  313.         mov ds:_code16a,eax
  314.         or dword ptr ds:gdt32code16[2],eax
  315.         or dword ptr ds:gdt32data16[2],eax
  316.         mov ebx,code32
  317.         shl ebx,4
  318.         mov ds:_code32a,ebx
  319.         or dword ptr ds:gdt32code32[2],ebx
  320.         or dword ptr ds:gdt32data32[2],ebx
  321.         add dword ptr ds:c_gdt32addx[2],ebx
  322.         mov eax,codeend
  323.         shl eax,4
  324.         sub eax,ebx
  325.         mov ds:_lomembase,eax
  326.         mov ds:realstackbase,eax
  327.         movzx eax,word ptr es:[2]
  328.         shl eax,4
  329.         sub eax,ebx
  330.         mov ds:_lomemtop,eax
  331.  
  332.         mov eax,STAKSIZE*16             ; get stack memory
  333.         call pregetlomem
  334.  
  335.         push es                         ; save PSP seg (DPMI chek kills ES)
  336.         pop fs
  337.  
  338.         mov ax,1687h                    ; chek for DPMI
  339.         int 2fh
  340.         or ax,ax
  341.         jz d_start
  342.  
  343.         call chek_VCPI                  ; chek for VCPI
  344.         jnc v_start
  345.  
  346.         call chek_V86                   ; chek for V86 mode
  347.  
  348.         mov ax,4300h                    ; chek for XMS
  349.         int 2fh
  350.         cmp al,80h
  351.         je x_start
  352.  
  353.         jmp c_start                     ; custom system start
  354. ;─────────────────────────────────────────────────────────────────────────────
  355. enableA20:                              ; hardware enable gate A20
  356.         xor ax,ax
  357.         mov fs,ax
  358.         dec ax
  359.         mov gs,ax
  360.         call testA20
  361.         je short enableA20done
  362.         in al,92h                       ; PS/2 A20 enable
  363.         or al,2
  364.         jmp short $+2
  365.         jmp short $+2
  366.         jmp short $+2
  367.         out 92h,al
  368.         call testA20
  369.         je short enableA20done
  370.         call enableA20o1                ; AT A20 enable
  371.         jnz short enableA20wait
  372.         mov al,0d1h
  373.         out 64h,al
  374.         call enableA20o1
  375.         jnz short enableA20wait
  376.         mov al,0dfh
  377.         out 60h,al
  378.         push offset enableA20wait
  379. enableA20o1:
  380.         mov ecx,20000h
  381. enableA20o1l:
  382.         jmp short $+2
  383.         jmp short $+2
  384.         jmp short $+2
  385.         in al,64h
  386.         test al,2
  387.         loopnz enableA20o1l
  388. enableA20done:
  389.         ret
  390. ;-----------------------------------------------------------------------------
  391. enableA20wait:                          ; wait for A20
  392.         mov al,36h
  393.         out 43h,al
  394.         xor al,al
  395.         out 40h,al
  396.         out 40h,al
  397.         mov cx,800h
  398. enableA20waitl0:
  399.         call testA20
  400.         je enableA20done
  401.         in al,40h
  402.         in al,40h
  403.         mov ah,al
  404. enableA20waitl1:
  405.         in al,40h
  406.         in al,40h
  407.         cmp al,ah
  408.         je enableA20waitl1
  409.         loop enableA20waitl0
  410.         mov dx,offset errmsg4
  411.         jmp exit16err
  412. ;-----------------------------------------------------------------------------
  413. testA20:                                ; Test for enabled A20
  414.         mov al,fs:[0]
  415.         mov ah,al
  416.         not al
  417.         mov gs:[10h],al
  418.         cmp ah,fs:[0]
  419.         mov fs:[0],ah
  420.         ret
  421. ;─────────────────────────────────────────────────────────────────────────────
  422. ; BL=low PIC val, BH=high PIC val
  423. setintslots:                            ; set int nums in table to PIC vals
  424.         mov edi,offset ds:intslottbl
  425.         mov cl,8
  426. setintslotsl0:
  427.         mov [di],bl
  428.         inc di
  429.         inc bl
  430.         dec cl
  431.         jnz setintslotsl0
  432.         mov cl,8
  433. setintslotsl1:
  434.         mov [di],bh
  435.         inc di
  436.         inc bh
  437.         dec cl
  438.         jnz setintslotsl1
  439.         ret
  440.  
  441. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  442. ; 16 bit DPMI system data
  443. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  444. d_errmsg0       db      'DPMI host is not 32bit!!!',7,'$'
  445. d_errmsg1       db      'Ran out of DPMI descriptors!!!',7,'$'
  446. d_errmsg2       db      'Couldn''t set DPMI descriptors as needed!!!',7,'$'
  447. d_errmsg3       db      'Couldn''t enter 32bit protected mode!!!',7,'$'
  448.  
  449. d_enterpmode    dw      ?,?             ; DPMI switch to pmode addx
  450. d_pspsel        dw      ?               ; stupid PSP selector
  451. d_oldenvsegsel  dw      ?               ; stupid selector we dont want
  452.  
  453. d_switchaddx    dd      ?               ; switch to pmode addx
  454. d_saveaddx      dd      ?               ; save/restore state addx
  455.  
  456. d_nintoff       dd      offset dp_irq0,offset dp_irq1,offset dp_irq2,offset dp_irq3
  457.                 dd      offset dp_irq4,offset dp_irq5,offset dp_irq6,offset dp_irq7
  458.                 dd      offset dp_irq8,offset dp_irq9,offset dp_irqa,offset dp_irqb
  459.                 dd      offset dp_irqc,offset dp_irqd,offset dp_irqe,offset dp_irqf
  460.                 dd      offset dp_int33,offset dp_int32,offset dp_int33,offset dp_int32
  461. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  462. ; 16 bit DPMI system code
  463. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  464. ;═════════════════════════════════════════════════════════════════════════════
  465. d_retreal:                              ; Return to real mode
  466.         mov ax,205h                     ; restore all int vektorz needed
  467.         mov edi,19
  468. d_retreall0:
  469.         mov bl,ds:intslottbl[edi]
  470.         lea ebp,[edi*2+edi]
  471.         mov edx,dword ptr ds:dp_ointbuf[ebp*2]
  472.         mov cx,word ptr ds:dp_ointbuf[ebp*2+4]
  473.         int 31h
  474.         sub di,1
  475.         jnc d_retreall0
  476.         jmp short d_exit
  477. ;─────────────────────────────────────────────────────────────────────────────
  478. d_exit16err:                            ; DPMI Exit with error message
  479.         mov ds:v86r_ds,code16
  480.         mov ds:v86r_ah,9
  481.         mov ax,300h
  482.         mov bx,21h
  483.         xor cx,cx
  484.         mov edi,offset ds:v86r_edi
  485.         push ds
  486.         pop es
  487.         int 31h
  488. ;─────────────────────────────────────────────────────────────────────────────
  489. d_exit:                                 ; DPMI exit to real mode
  490.         mov es,d_pspsel                 ; restore env selector
  491.         mov ax,d_oldenvsegsel
  492.         mov es:[2ch],ax
  493.         jmp exit
  494. ;═════════════════════════════════════════════════════════════════════════════
  495. d_start:                                ; Start in a crappy DPMI system
  496.         or ds:_sysbyte0,3               ; set system type DPMI byte
  497.  
  498.         test bl,1                       ; must be 32bit DPMI
  499.         mov dx,offset d_errmsg0
  500.         jz exit16err
  501.  
  502.         mov d_enterpmode[0],di          ; store enter addx
  503.         mov d_enterpmode[2],es
  504.         push word ptr fs:[2ch]          ; preserve old env seg
  505.  
  506.         movzx eax,si                    ; get mem for DPMI blok
  507.         shl eax,4
  508.         call pregetlomem
  509.         shr eax,4
  510.         add ax,code32
  511.         mov es,ax
  512.  
  513.         mov ax,1                        ; switch to pmode
  514.         call dword ptr d_enterpmode
  515.         cli                             ; I don't trust DPMI
  516.         mov dx,offset d_errmsg3
  517.         jc exit16err
  518.         mov ds:v86r_dx,offset d_errmsg1 ; prepare for abort maybe
  519.         pop ax                          ; swap old env seg with selector
  520.         xchg ax,es:[2ch]
  521.         mov d_oldenvsegsel,ax
  522.         mov d_pspsel,es                 ; store stupid selectors
  523.         mov ds:data16sel,ds
  524.         mov ds:code16sel,cs
  525.         mov ds:code16off,offset d_retreal       ; set return to real mode addx
  526.         mov ds:_setirqvect,offset dp_setirqvect ; modify some crap
  527.         mov ds:_getirqvect,offset dp_getirqvect
  528.         mov ds:_setselector,offset dp_setselector
  529.  
  530.         push ds                         ; no more need for PSP
  531.         pop es
  532.         mov ax,3                        ; get selector increment value
  533.         int 31h
  534.         mov bx,ax
  535.         xor ax,ax                       ; get needed selectors
  536.         mov cx,3+SELECTORS
  537.         int 31h
  538.         jc d_exit16err
  539.  
  540.         mov si,ax                       ; set up descriptors
  541.         mov ds:_selcode,ax
  542.         lea ecx,[eax+ebx]
  543.         mov ds:_seldata,cx
  544.         lea ebp,[ecx+ebx]
  545.         mov ds:_selzero,bp
  546.         lea eax,[ebp+ebx]
  547. if SELECTORS ne 0
  548.         mov ds:selectorbase,ax
  549.         mov ds:selectorinc,bx
  550. endif
  551.         mov ds:v86r_dx,offset d_errmsg2
  552.         mov ax,0ch                      ; set descriptors from GDT
  553.         mov bx,si
  554.         mov edi,offset ds:gdt32code32
  555.         or byte ptr [edi+5],60h
  556.         int 31h
  557.         jc d_exit16err
  558.         mov bx,cx
  559.         mov edi,offset ds:gdt32data32
  560.         or byte ptr [edi+5],60h
  561.         int 31h
  562.         jc d_exit16err
  563.         mov bx,bp
  564.         mov edi,offset ds:gdt32zero32
  565.         or byte ptr [edi+5],60h
  566.         int 31h
  567.         jc d_exit16err
  568. if SELECTORS ne 0
  569.         mov bx,ds:selectorbase          ; set up extra allocatable selectors
  570.         mov dx,SELECTORS
  571. d_startl1:
  572.         int 31h
  573.         jc d_exit16err
  574.         add bx,ds:selectorinc
  575.         dec dx
  576.         jnz d_startl1
  577. endif
  578.         mov es,cx                       ; ES, FS, and GS what they should be
  579.         mov fs,cx
  580.         mov gs,bp
  581.  
  582.         mov edi,ds:_lomembase           ; chek and get extended memory
  583.         mov eax,ds:_lomemtop
  584.         sub eax,edi
  585.         cmp eax,48
  586.         mov ds:v86r_dx,offset errmsg1
  587.         jb d_exit16err
  588.         mov ax,500h
  589.         int 31h
  590.         mov eax,es:[edi+14h]
  591.         cmp eax,-1
  592.         jne short d_startf0
  593.         mov eax,(EXTMIN+3) shr 2
  594. d_startf0:
  595.         shl eax,12
  596.         mov edx,eax
  597.         shr eax,10
  598.         cmp eax,EXTMIN
  599.         mov ds:v86r_dx,offset errmsg3
  600.         jb d_exit16err
  601.         or edx,edx
  602.         jz short d_startf1
  603.         mov cx,dx
  604.         shld ebx,edx,16
  605.         mov ax,501h
  606.         int 31h
  607.         mov ds:v86r_dx,offset errmsg5
  608.         jc d_exit16err
  609.         shl ebx,16
  610.         mov bx,cx
  611.         sub ebx,ds:_code32a
  612.         mov ds:_himembase,ebx
  613.         add ebx,edx
  614.         mov ds:_himemtop,ebx
  615. d_startf1:
  616.  
  617.         mov ax,305h                     ; get save/restore state addxs
  618.         int 31h
  619.         mov ds:dp_savelen,ax
  620.         mov dword ptr ds:dp_saveaddx[0],edi
  621.         mov word ptr ds:dp_saveaddx[4],si
  622.         mov word ptr d_saveaddx[0],cx
  623.         mov word ptr d_saveaddx[2],bx
  624.         mov ax,306h                     ; get switch mode addxs
  625.         int 31h
  626.         mov dword ptr ds:dp_switchaddx[0],edi
  627.         mov word ptr ds:dp_switchaddx[4],si
  628.         mov word ptr d_switchaddx[0],cx
  629.         mov word ptr d_switchaddx[2],bx
  630.  
  631.         mov ax,400h                     ; set IRQ handlers to PIC values
  632.         int 31h
  633.         xchg dl,dh
  634.         mov bx,dx
  635.         call setintslots
  636.  
  637.         mov ah,2                        ; backup and set all int vektorz
  638.         mov si,ds:_selcode
  639.         mov edi,19
  640. d_startl0:
  641.         mov bl,ds:intslottbl[edi]
  642.         mov al,4
  643.         int 31h
  644.         lea ebp,[edi*2+edi]
  645.         mov dword ptr ds:dp_ointbuf[ebp*2],edx
  646.         mov word ptr ds:dp_ointbuf[ebp*2+4],cx
  647.         mov al,5
  648.         mov edx,d_nintoff[edi*4]
  649.         mov cx,si
  650.         int 31h
  651.         sub di,1
  652.         jnc d_startl0
  653.  
  654.         mov ax,es                       ; set up needed regs & go on to 32bit
  655.         mov ss,ax
  656.         add esp,ds:realstackbase
  657.         mov ds,ax
  658.         push dword ptr cs:_selcode
  659.         push offset p_start
  660.         db 66h,0cbh             ; 32bit RETF
  661.  
  662. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  663. ; 16bit VCPI system data
  664. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  665. v_errmsg0       db      'Incompatible VCPI PIC mappings!!!',7,'$'
  666.  
  667. v_pagedirseg    dw      ?               ; seg of page directory
  668. v_pagebase      dw      0               ; first page of himem (*4)+1000h
  669. v_pagetop       dw      0               ; top page of himem (*4)+1000h
  670.  
  671. v_ss_cr3        dd      ?               ; new CR3 for pmode (physical)
  672. v_ss_gdtaddxptr dw      c_gdt32addx,0   ; ptr to GDT data for pmode
  673. v_ss_idtaddxptr dw      c_idt32addx,0   ; ptr to IDT data for pmode
  674. v_ss_ldtsel     dw      0               ; don't need no stinkin LDTs
  675. v_ss_trsel      dw      30h             ; task state segment selector
  676. v_ss_dest       dd      ?               ; start in pmode EIP
  677.                 dw      20h             ; start in pmode CS
  678. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  679. ; 16bit VCPI system code
  680. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  681. ;═════════════════════════════════════════════════════════════════════════════
  682. v_retreal:                              ; VCPI return to real mode
  683.         movzx edi,exitrout
  684.         mov esi,esp
  685.         sub esi,ds:realstackbase
  686.         mov cx,code16
  687. ;═════════════════════════════════════════════════════════════════════════════
  688. ; EDI=offset to jump to, ESI=real mode stack ptr, CX=real mode DS
  689. v_retreal0:                             ; VCPI go to real mode
  690.         sub esp,8
  691.         push ecx
  692.         push dword ptr ds:v86r_es
  693.         dw 06866h,codeend,0     ; PUSH dword codeend
  694.         push esi
  695.         pushfd
  696.         dw 06866h,code16,0      ; PUSH dword code16
  697.         push edi
  698.         mov ax,gs
  699.         mov ds,ax
  700.         mov ax,0de0ch
  701.         call cs:vp_vcpipmentry
  702. ;─────────────────────────────────────────────────────────────────────────────
  703. v_exit:                                 ; VCPI exit (clean up pages)
  704.         mov es,v_pagedirseg
  705.         mov si,v_pagebase
  706.         mov cx,v_pagetop
  707.         sub cx,si
  708.         jbe short v_exitf0
  709. v_exitl0:
  710.         mov edx,es:[si]
  711.         and dx,0f000h
  712.         mov ax,0de05h
  713.         int 67h
  714.         add si,4
  715.         sub cx,4
  716.         jnz v_exitl0
  717. v_exitf0:
  718.         jmp exit
  719. ;─────────────────────────────────────────────────────────────────────────────
  720. v_exiterr1:                             ; VCPI not enough low mem exit
  721.         mov dx,offset errmsg1
  722.         jmp exit16err
  723. ;═════════════════════════════════════════════════════════════════════════════
  724. v_start:                                ; start continues from VCPI
  725.         or ds:_sysbyte0,2               ; set system type VCPI byte
  726.         mov ds:code16off,offset v_retreal       ; VCPI return to real mode
  727.         mov c_idt32handler[48h],offset vp_int33 ; VCPI safe int handlers
  728.         mov c_idt32handler[4ch],offset vp_int32
  729.         mov ds:cp_v86irqintr[4],offset vp_int33f0 ; VCPI IRQ safe int routine
  730.         mov int32m0,VINT32              ; VCPI real INT32
  731.  
  732.         mov ax,0de0ah                   ; get PIC mappings
  733.         int 67h
  734.         mov bh,cl
  735.         mov dx,offset v_errmsg0         ; chek for compatible PIC mapping
  736.         cmp bl,bh
  737.         je exit16err
  738.         cmp bl,30h
  739.         je exit16err
  740.         cmp bh,30h
  741.         je exit16err
  742.         mov ax,70h                      ; compatible, get highest needed num
  743.         cmp al,bl
  744.         ja short v_startf1
  745.         mov al,bl
  746. v_startf1:
  747.         cmp al,bh
  748.         ja short v_startf2
  749.         mov al,bh
  750. v_startf2:
  751.         add al,7
  752.         mov c_numofintvects,al
  753.         lea eax,[eax*8+7]               ; set limit of IDT
  754.         mov c_idt32addx,ax
  755.         call setintslots                ; set int slots needed
  756.         movzx eax,ax
  757.         add eax,2068h+1
  758.         call pregetlomem                ; allocate TSS, IO bitmap, and IDT
  759.         mov ds:cp_tssesp0ptr,eax
  760.         mov eax,ds:_code16a             ; adjust mode switch structure
  761.         add dword ptr v_ss_gdtaddxptr,eax
  762.         add dword ptr v_ss_idtaddxptr,eax
  763.  
  764.         mov exitrout,offset v_exit      ; set VCPI cleanup exit
  765.  
  766.         mov eax,ds:_lomembase           ; align lomem base on a page
  767.         mov ebx,ds:_code32a
  768.         add ebx,eax
  769.         lea ecx,[ebx+0fffh]
  770.         and ecx,0fffff000h
  771.         sub ebx,ecx
  772.         sub eax,ebx
  773.         mov ds:_lomembase,eax
  774.         mov ebp,ds:_lomemtop            ; get available low memory
  775.         sub ebp,eax
  776.         sub ebp,LOWMIN*1024             ; die if not enough
  777.         jc v_exiterr1
  778.         cmp ebp,8192
  779.         jb v_exiterr1
  780.  
  781.         shld eax,ecx,28                 ; get segment and clear all pages
  782.         mov v_pagedirseg,ax
  783.         mov es,ax
  784.         xor di,di
  785.         mov cx,2048
  786.         xor eax,eax
  787.         rep stos dword ptr es:[di]
  788.         mov di,1000h                    ; get VCPI pmode interface
  789.         mov esi,offset ds:gdt32vcpi
  790.         mov ax,0de01h
  791.         int 67h
  792.         mov dword ptr ds:vp_vcpipmentry,ebx
  793.  
  794.         mov v_pagebase,di               ; set up and go through allocation
  795.         mov v_pagetop,di
  796.         movzx eax,di
  797.         sub eax,1000h
  798.         shl eax,10
  799.         sub eax,ds:_code32a
  800.         mov ds:_himembase,eax
  801.         mov ebx,8192
  802. v_startl2:
  803.         mov ax,0de04h
  804.         int 67h
  805.         or ah,ah
  806.         jnz short v_startl2d
  807.         test di,0fffh
  808.         jnz short v_startf4
  809.         add ebx,4096
  810.         cmp ebx,ebp
  811.         jbe short v_startf4
  812.         mov v_pagetop,di
  813.         mov ax,0de05h
  814.         int 67h
  815.         jmp v_exiterr1
  816. v_startf4:
  817.         and dx,0f000h
  818.         or dl,7
  819.         mov es:[di],edx
  820.         add di,4
  821.         jnc v_startl2
  822. v_startl2d:
  823.         mov v_pagetop,di
  824.         lea si,[di-1000h]
  825.         movzx eax,si
  826.         shl eax,10
  827.         sub eax,ds:_code32a
  828.         mov ds:_himemtop,eax
  829.         sub di,v_pagebase
  830.         cmp di,EXTMIN
  831.         mov dx,offset errmsg3
  832.         jb exit16err
  833.         add ds:_lomembase,ebx
  834.  
  835.         movzx ebx,v_pagedirseg          ; set up physical addresses
  836.         shr ebx,8
  837.         mov eax,es:[ebx*4+1000h]
  838.         mov v_ss_cr3,eax
  839.         xor di,di
  840. v_startl3:
  841.         inc ebx
  842.         mov eax,es:[ebx*4+1000h]
  843.         and ax,0f000h
  844.         or al,7
  845.         stos dword ptr es:[di]
  846.         sub si,1000h
  847.         ja v_startl3
  848.  
  849.         mov edi,offset c_startf1        ; offset to jump to in pmode
  850.         mov ebx,ds:cp_tssesp0ptr
  851.         jmp v_switchtopmode             ; duh?
  852.  
  853. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  854. ; 16 bit XMS system data
  855. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  856. x_calladdx      dd      ?               ; XMS driver addx
  857. x_handle        dw      0fedch          ; XMS handle of extended memory
  858. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  859. ; 16 bit XMS system code
  860. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  861. ;─────────────────────────────────────────────────────────────────────────────
  862. x_exit:                                 ; XMS exit (clean up allocation)
  863.         mov ax,cs
  864.         mov ds,ax
  865.         mov dx,x_handle
  866.         mov ah,0dh
  867.         call x_calladdx
  868.         mov ah,0ah
  869.         call x_calladdx
  870.         jmp exit
  871. ;─────────────────────────────────────────────────────────────────────────────
  872. x_exiterr5:                             ; exit with error message 5
  873.         mov dx,offset errmsg5
  874.         jmp exit16err
  875. ;═════════════════════════════════════════════════════════════════════════════
  876. x_start:                                ; start in an XMS system
  877.         or ds:_sysbyte0,1               ; set system type XMS byte
  878.  
  879.         mov ax,4310h                    ; get XMS driver addx
  880.         int 2fh
  881.         mov word ptr x_calladdx[0],bx
  882.         mov word ptr x_calladdx[2],es
  883.  
  884.         mov ah,3                        ; XMS enable A20
  885.         call x_calladdx
  886.         or ax,ax
  887.         mov dx,offset errmsg4
  888.         jz exit16err
  889.  
  890.         mov ah,8                        ; chek and get extended memory
  891.         call x_calladdx
  892.         sub ax,64
  893.         jnc short x_startf0
  894.         xor ax,ax
  895. x_startf0:
  896.         cmp ax,EXTMIN
  897.         mov dx,offset errmsg3
  898.         jb exit16err
  899.         mov dx,ax
  900.         movzx ecx,ax
  901.         shl ecx,10
  902.         mov ah,9
  903.         call x_calladdx
  904.         or ax,ax
  905.         jz x_exiterr5
  906.         mov x_handle,dx
  907.         mov exitrout,offset x_exit
  908.         mov ah,0ch
  909.         call x_calladdx
  910.         or ax,ax
  911.         jz x_exiterr5
  912.         shrd eax,edx,16
  913.         mov ax,bx
  914.         sub eax,ds:_code32a
  915.         mov ds:_himembase,eax
  916.         add eax,ecx
  917.         mov ds:_himemtop,eax
  918.  
  919.         jmp c_startf0                   ; go on to custom start
  920.  
  921. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  922. ; 16 bit custom system data
  923. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  924. c_idt16addx     dw      3ffh, 0,0       ; default real mode IDT addx&limit
  925. c_idt32addx     dw      3bfh, ?,?       ; 32bit IDT addx&limit
  926. c_gdt32addx     dw      04fh+SELECTORS*8; 32bit GDT addx&limit
  927.                 dd      offset gdt32    ;
  928.  
  929. c_numofintvects db      77h             ; number of int vects needed -1
  930. c_idt32handler  dd      offset cp_irq0,offset cp_irq1,offset cp_irq2,offset cp_irq3
  931.                 dd      offset cp_irq4,offset cp_irq5
  932.                 dd      offset cp_irq6,offset cp_irq7,offset cp_irq8,offset cp_irq9
  933.                 dd      offset cp_irqa,offset cp_irqb
  934.                 dd      offset cp_irqc,offset cp_irqd,offset cp_irqe,offset cp_irqf
  935.                 dd      offset cp_int35,offset cp_int34,offset cp_int33,offset cp_int32,offset cp_int31
  936.                 dd      offset cp_exc0,offset cp_exc1,offset cp_exc2,offset cp_exc3
  937.                 dd      offset cp_exc4,offset cp_exc5
  938.                 dd      offset cp_exc6,offset cp_exc7,offset cp_exc8,offset cp_exc9
  939.                 dd      offset cp_exca,offset cp_excb
  940.                 dd      offset cp_excc,offset cp_excd,offset cp_exce
  941. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  942. ; 16 bit custom system code
  943. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  944. ;═════════════════════════════════════════════════════════════════════════════
  945. c_irqreal:                              ; real mode IRQ
  946.         pushf
  947.         push cs
  948.         push offset icreald2
  949.         jmp icreal
  950. ;-----------------------------------------------------------------------------
  951. c_retreal1:                             ; load some real mode stuff & exit
  952.         mov ax,codeend
  953.         mov ss,ax
  954.         mov esp,STAKSIZE*10h
  955.         jmp exitrout
  956. ;═════════════════════════════════════════════════════════════════════════════
  957. c_retreal0:                             ; load real mode IDT and set PE=0
  958.         mov ax,28h
  959.         mov ds,ax
  960.         mov es,ax
  961.         mov fs,ax
  962.         mov gs,ax
  963.         mov ss,ax
  964.         lidt fword ptr c_idt16addx
  965.         mov eax,cr0
  966.         and al,0feh
  967.         mov cr0,eax
  968.         db 0eah                 ; JMP FAR PTR c_retreal0m0
  969. c_retreal0m0    dw c_sicreal,code16
  970. ;-----------------------------------------------------------------------------
  971. c_sicreal:                              ; safe real mode int or call
  972.         mov ax,codeend
  973.         mov ss,ax
  974.         mov ds,cs:v86r_ds
  975.         mov es,cs:v86r_es
  976.         db 0eah                 ; JMP FAR PTR c_sicrealm0
  977. c_sicrealm0     dw      ?,code16;
  978. ;═════════════════════════════════════════════════════════════════════════════
  979. c_retreal:                              ; return to real mode
  980.         mov c_retreal0m0,offset c_retreal1
  981.         mov esp,STAKSIZE*10h
  982.         jmp c_retreal0
  983. ;═════════════════════════════════════════════════════════════════════════════
  984. c_start:                                ; custom only start
  985.         call enableA20                  ; enable that stupid A20 thingy
  986.  
  987.         mov ah,88h                      ; chek and get extended mem
  988.         int 15h
  989.         cmp ax,EXTMIN
  990.         mov dx,offset errmsg3
  991.         jb exit16err
  992.         movzx eax,ax
  993.         shl eax,10
  994.         mov ebx,100000h
  995.         sub ebx,ds:_code32a
  996.         mov ds:_himembase,ebx
  997.         add eax,ebx
  998.         mov ds:_himemtop,eax
  999. ;═════════════════════════════════════════════════════════════════════════════
  1000. c_startf0:                              ; start continues from custom or XMS
  1001.         mov int32m0,CINT32              ; raw/XMS real INT32
  1002.         mov eax,2428h                   ; allocate TSS, IO bitmap, and IDT
  1003.         call pregetlomem
  1004.         mov ebx,eax
  1005.  
  1006.         lgdt fword ptr c_gdt32addx      ; switch to pmode
  1007.         mov eax,cr0
  1008.         or al,1
  1009.         mov cr0,eax
  1010.         db 0eah
  1011.         dw $+4,20h
  1012. ;-----------------------------------------------------------------------------
  1013. ; EBX->TSS
  1014. c_startf1:                              ; in 16bit pmode
  1015.         mov ax,28h                      ; set up segregs
  1016.         mov ds,ax
  1017.         mov al,18h
  1018.         mov gs,ax
  1019.         mov al,10h
  1020.         mov es,ax
  1021.         mov fs,ax
  1022.         mov ss,ax
  1023.         mov esp,STAKSIZE*16
  1024.         add esp,ds:realstackbase
  1025.  
  1026.         mov word ptr v_ss_dest[4],8     ; VCPI enter 32bit pmode from now on
  1027.         lea eax,[ebx+4]                 ; addx of ESP0 in TSS
  1028.         mov ds:cp_tssesp0ptr,eax
  1029.         mov ebp,ds:_code32a             ; TSS location in mem to GDT
  1030.         lea eax,[ebx+ebp]
  1031.         mov ecx,offset ds:gdt32task     ; set up task
  1032.         or dword ptr ds:[ecx+2],eax
  1033.         mov byte ptr ds:[ecx+5],89h
  1034.         mov cx,30h
  1035.         ltr cx
  1036.         add eax,2068h                   ; set up IDT
  1037.         mov ecx,offset c_idt32addx
  1038.         mov dword ptr [ecx+2],eax
  1039.         lidt fword ptr [ecx]
  1040.  
  1041.         mov dword ptr es:[ebx+8],10h    ; set up TSS stuff (EBX->TSS)
  1042.         mov edi,104
  1043.         mov es:[ebx+102],di
  1044.         mov word ptr es:[ebx+100],0
  1045.         add edi,ebx                     ; fill IO bitmap with 0
  1046.         xor eax,eax
  1047.         mov ecx,800h
  1048.         rep stos dword ptr es:[edi]
  1049.  
  1050.         mov ds:cp_idt32ptr,edi          ; set up blank IDT entries
  1051.         movzx esi,c_numofintvects
  1052. c_startl0:
  1053.         mov dword ptr es:[edi+esi*8],80000h+offset cp_excf
  1054.         mov dword ptr es:[edi+esi*8+4],8e00h
  1055.         sub si,1
  1056.         jnc c_startl0
  1057.         mov si,23h                      ; necessary IDT entries
  1058. c_startl1:
  1059.         movzx ebp,ds:intslottbl[esi]
  1060.         mov eax,c_idt32handler[esi*4]
  1061. ;       cmp bp,13
  1062. ;       jne short c_startl1c
  1063. ;       mov ds:cp_int13vect,eax
  1064. ;       mov eax,offset cp_excd
  1065. c_startl1c:
  1066.         mov es:[edi+ebp*8],ax
  1067.         sub si,1
  1068.         jnc c_startl1
  1069.  
  1070.         mov edi,offset p_start          ; set up regs & go on to 32bit
  1071.     mov ax,10h
  1072.         mov ds,ax
  1073. ;-----------------------------------------------------------------------------
  1074. c_gotopmode:                ; jump to 32bit pmode
  1075.         pushfd                          ; set eflags: NT=0, IOPL=3
  1076.         pop eax
  1077.         and ah,0bfh
  1078.         or ah,30h
  1079.         push eax
  1080.         popfd
  1081.         dw 6866h,8,0            ; PUSH dword 8
  1082.     push edi
  1083.         db 66h,0cbh             ; 32bit RETF
  1084.  
  1085. code16  ends
  1086.  
  1087. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  1088. ; 32bit pmode code
  1089. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  1090. code32  segment para public use32
  1091.         assume cs:code32, ds:code32
  1092.         org 0
  1093.  
  1094. extrn   _main:near
  1095.  
  1096. public  _exit, _ret, _getmem, _getlomem, _gethimem, _lomemsize, _himemsize
  1097. public  _getirqmask, _setirqmask, _getselector, _freeselector, _rmpmirqset
  1098. public  _rmpmirqfree
  1099.  
  1100. public  v86r_eax, v86r_ebx, v86r_ecx, v86r_edx, v86r_esi, v86r_edi, v86r_ebp
  1101. public  v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp
  1102. public  v86r_al, v86r_ah, v86r_bl, v86r_bh, v86r_cl, v86r_ch, v86r_dl, v86r_dh
  1103. public  v86r_ds, v86r_es, v86r_fs, v86r_gs
  1104. public  _selcode, _seldata, _selzero, _lomembase, _lomemtop, _himembase
  1105. public  _himemtop, _pspa, _code16a, _code32a, _getirqvect, _setirqvect
  1106. public  _sysbyte0, _irqmode, _setselector, _exitcode
  1107. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1108. ; 32 bit common system data
  1109. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1110. _lomembase      dd      ?               ; low mem base for allocation
  1111. _lomemtop       dd      ?               ; top of low mem
  1112. _himembase      dd      0               ; high mem base for allocation
  1113. _himemtop       dd      0               ; top of high mem
  1114. _pspa           dd      ?               ; offset of start of PSP from 0
  1115. _code16a        dd      ?               ; offset of start of 16bit code from 0
  1116. _code32a        dd      ?               ; offset of start of 32bit code from 0
  1117. _selcode        dw      8               ; code segment selector
  1118. _seldata        dw      10h             ; data segment alias for code
  1119. _selzero        dw      18h             ; data segment starting at 0:0
  1120. _irqmode        dw      0ffffh          ; IRQ mode bits: 0=normal, 1=safe
  1121.                 db      0ffh            ; misc byte, has to follow _irqmode
  1122. _sysbyte0       db      0               ; system bits:
  1123.                                         ;  0-1: 0=raw, 1=XMS, 2=VCPI, 3=DPMI
  1124. _exitcode       db      0               ; exit code for int21h ah=4ch
  1125.  
  1126. align 4
  1127. _getirqvect     dd      cp_getirqvect   ; get IRQ handler offset routine addx
  1128. _setirqvect     dd      cp_setirqvect   ; set IRQ handler offset routine addx
  1129. _setselector    dd      cp_setselector  ; set a selector addx offset addx
  1130.  
  1131. gdt32           dq      0
  1132. gdt32code32     db      0ffh,0ffh,0,0,0,9ah,0cfh,0
  1133. gdt32data32     db      0ffh,0ffh,0,0,0,92h,0cfh,0
  1134. gdt32zero32     db      0ffh,0ffh,0,0,0,92h,0cfh,0
  1135. gdt32code16     db      0ffh,0ffh,0,0,0,9ah,0,0
  1136. gdt32data16     db      0ffh,0ffh,0,0,0,92h,0,0
  1137. gdt32task       db      0ffh,0ffh,0,0,0,89h,0,0
  1138. gdt32vcpi       dq      3 dup(?)
  1139. if SELECTORS ne 0
  1140. gdt32free       db      SELECTORS dup(0ffh,0ffh,0,0,0,92h,0cfh,0)
  1141. endif
  1142.  
  1143. v86r_edi        label   dword           ; vregs for pmode<>real communication
  1144. v86r_di         dw      ?, ?            ;  needz to stay this way cuz its a
  1145. v86r_esi        label   dword           ;  stupid DPMI structure thingy
  1146. v86r_si         dw      ?, ?
  1147. v86r_ebp        label   dword
  1148. v86r_bp         dw      ?, ?
  1149.                 dd      0
  1150. v86r_ebx        label   dword
  1151. v86r_bx         label   word
  1152. v86r_bl         db      ?
  1153. v86r_bh         db      ?, ?,?
  1154. v86r_edx        label   dword
  1155. v86r_dx         label   word
  1156. v86r_dl         db      ?
  1157. v86r_dh         db      ?, ?,?
  1158. v86r_ecx        label   dword
  1159. v86r_cx         label   word
  1160. v86r_cl         db      ?
  1161. v86r_ch         db      ?, ?,?
  1162. v86r_eax        label   dword
  1163. v86r_ax         label   word
  1164. v86r_al         db      ?
  1165. v86r_ah         db      ?, ?,?
  1166. v86r_flags      dw      ?
  1167. v86r_es         dw      ?
  1168. v86r_ds         dw      ?
  1169. v86r_fs         dw      ?
  1170. v86r_gs         dw      ?
  1171.                 dd      0,0
  1172.  
  1173. oint1bvect      dd      ?               ; old real int 1bh vektor (ctrl+break)
  1174. oint32vect      dd      ?               ; old real int 32h vector
  1175. oirqmask        dw      ?               ; old port 21h and 0a1h masks
  1176. intslottbl      db      8,9,0ah,0bh,0ch,0dh,0eh,0fh,70h,71h,72h,73h,74h,75h,76h,77h
  1177.                 db      35h,34h,33h,32h,31h,0,1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh
  1178.  
  1179. if SELECTORS ne 0
  1180. selectorbase    dw      50h
  1181. selectorinc     dw      8
  1182. selectorfree    db      SELECTORS dup(0)
  1183. endif
  1184.  
  1185. code16off       dw      c_retreal       ; offset in 16bit of exit function
  1186. code16sel       dw      20h             ; 16bit pmode code selector
  1187. data16sel       dw      28h             ; 16bit pmode data selector
  1188.  
  1189. nextmodestack   dw      (STAKSIZE-STAKMAIN)*16  ; stack for next mode switch
  1190. realstackbase   dd      ?               ; linear ptr to beginning of codeend
  1191.  
  1192. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1193. ; 32 bit common system code
  1194. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1195. ;═════════════════════════════════════════════════════════════════════════════
  1196. p_cpmode2:                ; call pmode from V86
  1197.         mov gs,cx
  1198.         mov cl,10h
  1199.         mov ds,cx
  1200.         mov es,cx
  1201.         mov fs,cx
  1202.         sub nextmodestack,STAKPMODE*16
  1203.     push p_cpmodem2
  1204.     mov p_cpmodem2,V86CPMODED
  1205.         mov eax,[esp+22]
  1206.     mov p_cpmodem0,eax
  1207.         mov al,[esp+43]
  1208.     shr al,1
  1209.     and al,1
  1210.     add al,0fah
  1211.     mov p_cpmodem1,al
  1212.         jmp short p_cpmode
  1213. ;═════════════════════════════════════════════════════════════════════════════
  1214. p_cpmode1:                              ; call pmode, load all
  1215.         mov esp,ebx
  1216.         mov ax,10h
  1217.         mov ds,ax
  1218.         mov es,ax
  1219.         mov ss,ax
  1220. ;-----------------------------------------------------------------------------
  1221. p_cpmode0:                              ; call pmode, load FS and GS
  1222.         mov fs,_seldata
  1223.         mov gs,_selzero
  1224. ;-----------------------------------------------------------------------------
  1225. p_cpmode:                               ; call pmode routine from real
  1226.         push offset p_cpmoded
  1227.         cld
  1228.         mov eax,v86r_eax
  1229.         mov ecx,v86r_ecx
  1230.         mov edx,v86r_edx
  1231.         mov ebx,v86r_ebx
  1232.         mov esi,v86r_esi
  1233.         mov edi,v86r_edi
  1234.         mov ebp,v86r_ebp
  1235.         db 68h                  ; PUSH destination address
  1236. p_cpmodem0      dd      ?       ;
  1237. p_cpmodem1      db      ?       ; CLI or STI
  1238.         ret
  1239. ;-----------------------------------------------------------------------------
  1240. p_cpmoded:                              ; call to pmode done
  1241.         cli
  1242.         pushf
  1243.         pop v86r_flags
  1244.         mov v86r_eax,eax
  1245.         mov v86r_ecx,ecx
  1246.         mov v86r_edx,edx
  1247.         mov v86r_ebx,ebx
  1248.         mov v86r_esi,esi
  1249.         mov v86r_edi,edi
  1250.         mov v86r_ebp,ebp
  1251.         mov ecx,_code16a
  1252. p_cpmodem2        label word            ; return to real, modifiable to JMP
  1253. ;-----------------------------------------------------------------------------
  1254.         movzx ebx,gs:savedstakoff[ecx]  ; DPMI return to real mode
  1255.         mov dx,gs:savedstakseg[ecx]
  1256.         mov ax,code16
  1257.         mov cx,dx
  1258.         mov si,ax
  1259.         mov edi,offset int32d0
  1260.         jmp dp_switchaddx
  1261. ;-----------------------------------------------------------------------------
  1262. VCPMODED=(($-(p_cpmodem2+2))shl 8)+0ebh
  1263. p_cpmoded2:                             ; VCPI done with pmode
  1264.         movzx esi,gs:savedstakoff[ecx]
  1265.         mov cx,code16
  1266.         mov edi,offset int32d1
  1267.         db 0eah                 ; 16bit JMP FAR 20h:v_retreal0
  1268.         dw v_retreal0,0,20h     ;
  1269. ;-----------------------------------------------------------------------------
  1270. CCPMODED=(($-(p_cpmodem2+2))shl 8)+0ebh
  1271. p_cpmoded3:                             ; raw/XMS done with pmode
  1272.         mov gs:c_retreal0m0[ecx],offset int32d3
  1273.         db 0eah                 ; 16bit JMP FAR 20h:c_retreal0
  1274.         dw c_retreal0,0,20h     ;
  1275. ;-----------------------------------------------------------------------------
  1276. if ($-(p_cpmodem2+2)) gt 127
  1277.   err
  1278. endif
  1279. V86CPMODED=(($-(p_cpmodem2+2))shl 8)+0ebh
  1280. p_cpmoded4:                ; V86 done with pmode
  1281.     pop p_cpmodem2
  1282.         jmp cp_int3_d3
  1283. ;═════════════════════════════════════════════════════════════════════════════
  1284. p_start:                                ; common 32bit start
  1285.         mov eax,gs:[1bh*4]              ; neutralize crtl+break
  1286.         mov oint1bvect,eax
  1287.         db 65h,67h,0c7h,6       ; MOV DWORD PTR GS:[1bh*4],code16:nullint
  1288.         dw 1bh*4,nullint,code16 ;
  1289.         mov eax,gs:[32h*4]              ; set up for new real mode INT32
  1290.         mov oint32vect,eax
  1291.         db 65h,67h,0c7h,6       ; MOV DWORD PTR GS:[32h*4],code16:int32
  1292.         dw 32h*4,int32,code16   ;
  1293.         in al,21h                       ; save old PIC masks
  1294.         mov ah,al
  1295.         in al,0a1h
  1296.         mov oirqmask,ax
  1297.         jmp _main                       ; go to main code
  1298.  
  1299. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1300. ; Allocate any mem, (first cheks low, then high)
  1301. ; In:
  1302. ;   EAX - size requested
  1303. ; Out:
  1304. ;   CF=0 - memory allocated
  1305. ;   CF=1 - not enough mem
  1306. ;   EAX - linear pointer to mem or ?
  1307. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1308. _getmem:
  1309.         push eax
  1310.         call _getlomem
  1311.         jnc short getmemd
  1312.         pop eax
  1313.         jmp short _gethimem
  1314. getmemd:
  1315.         add esp,4
  1316. _ret:                                   ; generic RET instruction
  1317.         ret
  1318. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1319. ; Allocate some low mem
  1320. ; In:
  1321. ;   EAX - size requested
  1322. ; Out:
  1323. ;   CF=0 - memory allocated
  1324. ;   CF=1 - not enough mem
  1325. ;   EAX - linear pointer to mem or ?
  1326. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1327. _getlomem:
  1328.         add eax,_lomembase
  1329.         cmp eax,_lomemtop
  1330.         ja short getmemerr
  1331.         xchg eax,_lomembase
  1332.         clc
  1333.         ret
  1334. getmemerr:
  1335.         stc
  1336.         ret
  1337. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1338. ; Allocate some high mem
  1339. ; In:
  1340. ;   EAX - size requested
  1341. ; Out:
  1342. ;   CF=0 - memory allocated
  1343. ;   CF=1 - not enough mem
  1344. ;   EAX - linear pointer to mem or ?
  1345. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1346. _gethimem:
  1347.         add eax,_himembase
  1348.         cmp eax,_himemtop
  1349.         ja short getmemerr
  1350.         xchg eax,_himembase
  1351.         clc
  1352.         ret
  1353. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1354. ; Get amount of free low mem
  1355. ; Out:
  1356. ;   EAX - number of bytes free
  1357. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1358. _lomemsize:
  1359.         mov eax,_lomemtop
  1360.         sub eax,_lomembase
  1361.         ret
  1362. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1363. ; Get amount of free high mem
  1364. ; Out:
  1365. ;   EAX - number of bytes free
  1366. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1367. _himemsize:
  1368.         mov eax,_himemtop
  1369.         sub eax,_himembase
  1370.         ret
  1371. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1372. ; Get status of IRQ mask bit
  1373. ; In:
  1374. ;   BL - IRQ num (0-15)
  1375. ; Out:
  1376. ;   AL - status: 0=enabled, 1=disabled
  1377. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1378. _getirqmask:
  1379.         push ax
  1380.         in al,0a1h
  1381.         mov ah,al
  1382.         in al,21h
  1383.         xchg cl,bl
  1384.         shr ax,cl
  1385.         xchg cl,bl
  1386.         and al,1
  1387.         mov [esp],al
  1388.         pop ax
  1389.         ret
  1390. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1391. ; Set status of IRQ mask bit
  1392. ; In:
  1393. ;   BL - IRQ num (0-15)
  1394. ;   AL - status: 0=enabled, 1=disabled
  1395. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1396. _setirqmask:
  1397.         push ax bx cx dx
  1398.         mov cl,bl
  1399.         mov bx,0fffeh
  1400.         movzx dx,al
  1401.         rol bx,cl
  1402.         shl dx,cl
  1403.         in al,0a1h
  1404.         mov ah,al
  1405.         in al,21h
  1406.         and ax,bx
  1407.         or ax,dx
  1408.         out 21h,al
  1409.         mov al,ah
  1410.         out 0a1h,al
  1411.         pop dx cx bx ax
  1412.         ret
  1413. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1414. ; Set a real mode IRQ vect to redirect to pmode
  1415. ; In:
  1416. ;   BL - IRQ number
  1417. ;   EDX - offset of IRQ handler
  1418. ;   EDI -> 21 byte buffer for code stub created
  1419. ; Out:
  1420. ;   EAX - old seg:off of real mode IRQ handler
  1421. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1422. rmpmirqsetd0:
  1423. db 66h,52h              ; PUSH EDX
  1424. db 66h,0bah,?,?,?,?     ; MOV EDX,?
  1425. db 0cdh,32h             ; INT 32h
  1426. db 66h,5ah              ; POP EDX
  1427. db 0cfh                 ; IRET
  1428. db 9ch                  ; PUSHFD
  1429. db 0eh                  ; PUSH CS
  1430. db 0e8h,?,?,?,?         ; CALL ?
  1431. db 0c3h                 ; RET
  1432. ;-----------------------------------------------------------------------------
  1433. _rmpmirqset:
  1434.         push esi edi
  1435.         mov esi,offset rmpmirqsetd0
  1436.         lea eax,[edi+13]
  1437.         mov [esi+4],eax
  1438.         add eax,7
  1439.         sub eax,edx
  1440.         neg eax
  1441.         mov [esi+16],eax
  1442.         mov eax,edi
  1443.         movsd
  1444.         movsd
  1445.         movsd
  1446.         movsd
  1447.         movsd
  1448.         movsb
  1449.         add eax,_code32a
  1450.         shl eax,12
  1451.         shr ax,12
  1452.         movzx edi,bl
  1453.         cmp edi,8
  1454.         jb short rmpmirqsetf0
  1455.         add edi,60h
  1456. rmpmirqsetf0:
  1457.         xchg eax,gs:[edi*4+20h]
  1458.         pop edi esi
  1459.         ret
  1460. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1461. ; Reset a real more IRQ vect back to normal (just sets real mode IRQ vect)
  1462. ; In:
  1463. ;   BL - IRQ number
  1464. ;   EAX - seg:off of real mode IRQ handler
  1465. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1466. _rmpmirqfree:
  1467.         push ebx
  1468.         movzx ebx,bl
  1469.         cmp bl,8
  1470.         jb short rmpmirqfreef0
  1471.         add bl,60h
  1472. rmpmirqfreef0:
  1473.         mov gs:[ebx*4+20h],eax
  1474.         pop ebx
  1475.         ret
  1476. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1477. ; Allocate a selector
  1478. ; Out:
  1479. ;   CF=1 - selector not allocated
  1480. ;   CF=0 - selector allocated
  1481. ;   AX - 4G data selector or ?
  1482. ; Notes:
  1483. ;   The selector returned is for a 4G r/w data segment with an undefined base
  1484. ;    address.
  1485. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1486. _getselector:
  1487. if SELECTORS eq 0
  1488.         stc
  1489.         ret
  1490. else
  1491.         push ecx edi
  1492.         mov edi,offset selectorfree
  1493.         mov ecx,SELECTORS
  1494.         mov al,0
  1495.         repne scasb
  1496.         jne short getselectorf0
  1497.         mov byte ptr [edi-1],1
  1498.         sub ecx,SELECTORS-1
  1499.         neg ecx
  1500.         imul cx,selectorinc
  1501.         mov ax,selectorbase
  1502.         add ax,cx
  1503.         clc
  1504.         jmp short getselectorf1
  1505. getselectorf0:
  1506.         stc
  1507. getselectorf1:
  1508.         pop edi ecx
  1509.         ret
  1510. endif
  1511. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1512. ; Free an allocated selector
  1513. ; In:
  1514. ;   AX - selector
  1515. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1516. _freeselector:
  1517. if SELECTORS ne 0
  1518.         push eax dx
  1519.         sub ax,selectorbase
  1520.         xor dx,dx
  1521.         div selectorinc
  1522.         movzx eax,ax
  1523.         mov selectorfree[eax],0
  1524.         pop dx eax
  1525. endif
  1526.         ret
  1527. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1528. ; Exit to real mode
  1529. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1530. _exit:
  1531.         cli
  1532.         mov eax,oint1bvect              ; restore ctrl+break
  1533.         mov gs:[1bh*4],eax
  1534.         mov eax,oint32vect              ; restore real mode int 32h vector
  1535.         mov gs:[32h*4],eax
  1536.         mov ax,oirqmask                 ; restore PIC masks
  1537.         out 0a1h,al
  1538.         mov al,ah
  1539.         out 21h,al
  1540.         push code16sel                  ; go to 16bit pmode exit code
  1541.         push code16off
  1542.         mov ds,data16sel
  1543.         db 66h,0cbh             ; 16bit RETF
  1544.  
  1545. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1546. ; 32 bit DPMI system data
  1547. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1548. dp_switchaddx   df      ?               ; switch to real mode addx
  1549. dp_saveaddx     df      ?               ; save/restore state addx
  1550. dp_savelen      dw      0,0             ; length of state buffer
  1551. dp_savedstaksel dw      ?               ; current saved stack selector
  1552.  
  1553. dp_ointbuf      df      20 dup(?)       ; saved interrupt addx buffer
  1554. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1555. ; 32 bit DPMI system code
  1556. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1557. ;═════════════════════════════════════════════════════════════════════════════
  1558. dp_int32:                               ; DPMI INT32/34: CX:DX=seg:off
  1559.         pushad
  1560.         shl ecx,16
  1561.         mov cx,dx
  1562.         mov bp,offset callreal
  1563.         mov dl,1
  1564.         jmp short dp_int3_
  1565. ;═════════════════════════════════════════════════════════════════════════════
  1566. dp_int33:                               ; DPMI INT33/35: AL=int num
  1567.         pushad
  1568.         movzx eax,al
  1569.         mov ecx,gs:[eax*4]
  1570.         mov bp,offset intreal
  1571.         xor dl,dl
  1572. ;-----------------------------------------------------------------------------
  1573. dp_int3_:                               ; DPMI int or call to real mode
  1574.         mov ax,900h
  1575.         int 31h
  1576.         push ax
  1577.         and al,dl
  1578.         add al,0fah
  1579.         mov ebx,_code16a
  1580.         mov gs:icrealm0[ebx],al
  1581.         mov gs:icrealm1[ebx],ecx
  1582.         push cp_savedstakoff
  1583.         push dp_savedstaksel
  1584.         movzx ebx,nextmodestack
  1585.         lea eax,[ebx-STAKRMODE*16]
  1586.         mov nextmodestack,ax
  1587.         mov ax,ss
  1588.         mov es,ax
  1589.         sub esp,dword ptr dp_savelen
  1590.         mov edi,esp
  1591.         xor al,al
  1592.         call dp_saveaddx
  1593.         mov cp_savedstakoff,esp
  1594.         mov dp_savedstaksel,ss
  1595.         mov dx,codeend
  1596.         mov ax,v86r_ds
  1597.         mov cx,v86r_es
  1598.         movzx edi,bp
  1599.         mov si,code16
  1600.         jmp dp_switchaddx
  1601. ;-----------------------------------------------------------------------------
  1602. dp_int3_d:                              ; done with real mode int or call
  1603.         mov edi,esp
  1604.         mov al,1
  1605.         call dp_saveaddx
  1606.         add esp,dword ptr dp_savelen
  1607.         pop dp_savedstaksel
  1608.         pop cp_savedstakoff
  1609.         add nextmodestack,STAKRMODE*16
  1610.         mov bx,v86r_flags
  1611.         pop ax
  1612.         int 31h
  1613.         mov ax,ds
  1614.         mov es,ax
  1615.         mov fs,ax
  1616.         mov gs,_selzero
  1617.         jmp cp_int3_d2
  1618. ;═════════════════════════════════════════════════════════════════════════════
  1619. ; DPMI IRQ redirectors (needed to make all IRQ vector selectors = CS)
  1620. dp_irq0:
  1621.         jmp cs:dp_ointbuf[0]
  1622. dp_irq1:
  1623.         jmp cs:dp_ointbuf[6]
  1624. dp_irq2:
  1625.         jmp cs:dp_ointbuf[12]
  1626. dp_irq3:
  1627.         jmp cs:dp_ointbuf[18]
  1628. dp_irq4:
  1629.         jmp cs:dp_ointbuf[24]
  1630. dp_irq5:
  1631.         jmp cs:dp_ointbuf[30]
  1632. dp_irq6:
  1633.         jmp cs:dp_ointbuf[36]
  1634. dp_irq7:
  1635.         jmp cs:dp_ointbuf[42]
  1636. dp_irq8:
  1637.         jmp cs:dp_ointbuf[48]
  1638. dp_irq9:
  1639.         jmp cs:dp_ointbuf[54]
  1640. dp_irqa:
  1641.         jmp cs:dp_ointbuf[60]
  1642. dp_irqb:
  1643.         jmp cs:dp_ointbuf[66]
  1644. dp_irqc:
  1645.         jmp cs:dp_ointbuf[72]
  1646. dp_irqd:
  1647.         jmp cs:dp_ointbuf[78]
  1648. dp_irqe:
  1649.         jmp cs:dp_ointbuf[84]
  1650. dp_irqf:
  1651.         jmp cs:dp_ointbuf[90]
  1652.  
  1653. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1654. ; DPMI get IRQ handler offset
  1655. ; In:
  1656. ;   BL - IRQ num (0-0fh)
  1657. ; Out:
  1658. ;   EDX - offset of IRQ handler
  1659. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1660. dp_getirqvect:
  1661.         push ax ebx cx
  1662.         movzx ebx,bl
  1663.         mov bl,intslottbl[ebx]
  1664.         mov ax,204h
  1665.         int 31h
  1666.         pop cx ebx ax
  1667.         ret
  1668. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1669. ; DPMI set IRQ handler offset
  1670. ; In:
  1671. ;   BL - IRQ num (0-0fh)
  1672. ;   EDX - offset of IRQ handler
  1673. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1674. dp_setirqvect:
  1675.         push ax ebx cx
  1676.         movzx ebx,bl
  1677.         mov bl,intslottbl[ebx]
  1678.         mov cx,cs
  1679.         mov ax,205h
  1680.         int 31h
  1681.         pop cx ebx ax
  1682.         ret
  1683. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1684. ; Set the base addx for a selector
  1685. ; In:
  1686. ;   AX - selector
  1687. ;   EDX - linear base addx for selector
  1688. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1689. dp_setselector:
  1690. if SELECTORS ne 0
  1691.         push ax bx ecx
  1692.         shld ecx,edx,16
  1693.         mov bx,ax
  1694.         mov ax,7
  1695.         int 31h
  1696.         pop ecx bx ax
  1697. endif
  1698.         ret
  1699.  
  1700. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1701. ; 32 bit custom/XMS/VCPI system data
  1702. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1703. vp_vcpipmentry  df      3800000000h     ; VCPI entry point in pmode
  1704.  
  1705. cp_tssesp0ptr   dd      0               ; ptr to ESP0 in TSS, or null in VCPI
  1706. cp_idt32ptr     dd      ?               ; ptr to 32bit IDT
  1707. cp_int13vect    dd      0               ; interrupt vektor 13 ptr
  1708. cp_validexcdesp dd      0               ; valid ESP value for exc 13
  1709.  
  1710. cp_v86irqintr   dd      cp_int35f1,cp_int33f0   ; IRQ int call routines
  1711. cp_v86irqnum    db      ?               ; IRQ num for V86 mode
  1712. cp_v86irqmode   db      ?               ; IRQ mode for V86 mode (safe/norm)
  1713. cp_savedstakoff dd      ?               ; current saved stack offset
  1714. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1715. ; 32 bit custom/XMS/VCPI system code
  1716. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  1717. ;═════════════════════════════════════════════════════════════════════════════
  1718. cp_int31:                               ; INT 31h: AX=900h,901h,902h
  1719.         cmp al,1
  1720.         mov al,[esp+9]
  1721.         jb short cp_int31f0
  1722.         ja short cp_int31f1
  1723.         or byte ptr [esp+9],2
  1724.         jmp short cp_int31f1
  1725. cp_int31f0:
  1726.         and byte ptr [esp+9],0fdh
  1727. cp_int31f1:
  1728.         shr al,1
  1729.         and al,1
  1730.         iretd
  1731. ;═════════════════════════════════════════════════════════════════════════════
  1732. vp_int32:                               ; VCPI INT 32h: safe CX:DX=seg:off
  1733.         pushad
  1734.         mov ebp,offset callreal
  1735.         mov si,VICREAL1D
  1736.         mov bl,2
  1737.         jmp short cp_int34f0
  1738. ;═════════════════════════════════════════════════════════════════════════════
  1739. vp_int33:                               ; VCPI INT 33h: safe AL=int num
  1740.         pushad
  1741.         mov ebp,offset intreal
  1742. ;-----------------------------------------------------------------------------
  1743. vp_int33f0:
  1744.         mov si,VICREAL1D
  1745.         mov bl,2
  1746.         jmp short cp_int35f0
  1747. ;═════════════════════════════════════════════════════════════════════════════
  1748. cp_int32:                               ; INT 32h: safe CX:DX=seg:off
  1749.         pushad
  1750.         mov ebp,offset callreal
  1751.         mov si,CICREAL1D
  1752.         mov bl,1
  1753.         jmp short cp_int34f0
  1754. ;═════════════════════════════════════════════════════════════════════════════
  1755. cp_int33:                               ; INT 33h: safe AL=int num
  1756.         pushad
  1757.         mov ebp,offset intreal
  1758. ;-----------------------------------------------------------------------------
  1759. cp_int33f0:
  1760.         mov si,CICREAL1D
  1761.         mov bl,1
  1762.         jmp short cp_int35f0
  1763. ;═════════════════════════════════════════════════════════════════════════════
  1764. cp_int34:                               ; INT 34h: normal CX:DX=seg:off
  1765.         pushad
  1766.         mov ebp,offset callreal
  1767.         mov si,CICREAL0D
  1768.         xor bl,bl
  1769. ;-----------------------------------------------------------------------------
  1770. cp_int34f0:
  1771.         shl ecx,16
  1772.         mov cx,dx
  1773.         mov bh,1
  1774.         jmp short cp_int3_
  1775. ;═════════════════════════════════════════════════════════════════════════════
  1776. cp_int35:                               ; INT 35h: normal AL=int num
  1777.         pushad
  1778.         mov ebp,offset intreal
  1779. ;-----------------------------------------------------------------------------
  1780. cp_int35f1:
  1781.         mov si,CICREAL0D
  1782.         xor bl,bl
  1783. ;-----------------------------------------------------------------------------
  1784. cp_int35f0:
  1785.         movzx eax,al
  1786.         mov ecx,gs:[eax*4]
  1787.         xor bh,bh
  1788. ;-----------------------------------------------------------------------------
  1789. cp_int3_:                               ; int or call to real mode
  1790.         mov edi,[esp+40]
  1791.         shld eax,edi,23
  1792.         and al,bh
  1793.         add al,0fah
  1794.         mov edx,_code16a
  1795.         mov gs:icrealm0[edx],al
  1796.         mov gs:icrealm1[edx],ecx
  1797.         xchg gs:icrealm2[edx],si
  1798.         push si
  1799.         movzx esi,nextmodestack
  1800.         lea eax,[esi-STAKRMODE*16]
  1801.         mov nextmodestack,ax
  1802.         add eax,realstackbase
  1803.         mov edx,cp_tssesp0ptr
  1804.         push dword ptr [edx]
  1805.         mov [edx],eax
  1806.         sub eax,40
  1807.         push cp_validexcdesp
  1808.         mov cp_validexcdesp,eax
  1809.         push cp_savedstakoff
  1810.         mov cp_savedstakoff,esp
  1811.         cmp bl,1
  1812.         jb short cp_int3_n
  1813.         ja short vp_int3_s
  1814. ;-----------------------------------------------------------------------------
  1815. cp_int3_s:                              ; safe real mode int or call
  1816.         mov edx,_code16a
  1817.         mov gs:c_sicrealm0[edx],bp
  1818.         mov esp,esi
  1819.         db 0eah                 ; 16bit JMP FAR 20h:c_retreal0
  1820.         dw c_retreal0,0,20h     ;
  1821. ;-----------------------------------------------------------------------------
  1822. vp_int3_s:                              ; safe VCPI real mode int or call
  1823.         mov edi,ebp
  1824.         mov cx,v86r_ds
  1825.         mov ax,28h
  1826.         mov ds,ax
  1827.         db 0eah                 ; 16bit JMP FAR 20h:v_retreal0
  1828.         dw v_retreal0,0,20h     ;
  1829. ;-----------------------------------------------------------------------------
  1830. cp_int3_n:                              ; normal real mode int or call
  1831.         sub esp,8
  1832.         push dword ptr v86r_ds
  1833.         push dword ptr v86r_es
  1834.         db 68h                  ; 32bit PUSH codeend
  1835.         dd codeend              ;
  1836.         push esi
  1837.         or edi,20000h
  1838.         and di,0fdffh
  1839.         push edi
  1840.         db 68h                  ; 32bit PUSH code16
  1841.         dd code16               ;
  1842.         push ebp
  1843.         iretd
  1844. ;-----------------------------------------------------------------------------
  1845. cp_int3_d:                              ; done with real mode int or call
  1846.         mov ax,18h
  1847.         mov gs,ax
  1848.         mov ax,10h
  1849.         mov ds,ax
  1850.         mov es,ax
  1851.         mov fs,ax
  1852.         mov ss,ax
  1853.         mov esp,cp_savedstakoff
  1854.         pop cp_savedstakoff
  1855.         pop cp_validexcdesp
  1856.         mov ebx,cp_tssesp0ptr
  1857.         pop dword ptr [ebx]
  1858.         mov ebx,_code16a
  1859.         pop gs:icrealm2[ebx]
  1860. ;-----------------------------------------------------------------------------
  1861. cp_int3_d3:                             ; done from real mode pmode call
  1862.         add nextmodestack,STAKRMODE*16
  1863.         mov bx,v86r_flags
  1864. ;-----------------------------------------------------------------------------
  1865. cp_int3_d2:                ; done from DPMI also
  1866.         mov ax,[esp+40]
  1867.         and ax,not 8d5h
  1868.         and bx,8d5h
  1869.         or ax,bx
  1870.         mov [esp+40],ax
  1871.         popad
  1872.         iretd
  1873. ;═════════════════════════════════════════════════════════════════════════════
  1874. cp_excd:                                ; general protection violation
  1875.         cmp esp,cs:cp_validexcdesp      ; IRQ5 or exception
  1876.         je short cp_excdf0
  1877.         jmp cs:cp_int13vect
  1878. cp_excdf0:
  1879.         test byte ptr [esp+14],2        ; exception from V86?
  1880.         jnz short cp_excdv86
  1881.         pushad                          ; nope, pmode exception
  1882.         mov al,0dh
  1883.         jmp cp_exc
  1884. ;-----------------------------------------------------------------------------
  1885. cp_excdv86:                             ; violation from V86 mode
  1886.         add esp,4
  1887.         pushad
  1888.         mov cx,18h
  1889.         mov ds,cx
  1890.         movzx ebx,word ptr [esp+36]
  1891.         shl ebx,4
  1892.         add ebx,[esp+32]
  1893.         inc word ptr [esp+32]
  1894.         mov al,[ebx]
  1895.         mov edx,3
  1896.         cmp al,0cch
  1897.         je short cp_v86int
  1898.         mov dl,4
  1899.         cmp al,0ceh
  1900.         je short cp_v86int
  1901.         inc word ptr [esp+32]
  1902.         mov dl,[ebx+1]
  1903.         cmp dl,32h
  1904.         je p_cpmode2
  1905.         cmp dl,0ffh
  1906.         je cp_int3_d
  1907. ;-----------------------------------------------------------------------------
  1908. cp_v86int:                              ; need to simulate a real mode int
  1909.         movzx ebx,word ptr [esp+48]
  1910.         shl ebx,4
  1911.         sub word ptr [esp+44],6
  1912.         add ebx,[esp+44]
  1913.         mov ax,[esp+40]
  1914.         mov [ebx+4],ax
  1915.         and ah,0fch
  1916.         mov [esp+41],ah
  1917.         mov ax,[esp+36]
  1918.         mov [ebx+2],ax
  1919.         mov ax,[esp+32]
  1920.         mov [ebx],ax
  1921.         mov eax,[edx*4]
  1922.         mov [esp+32],ax
  1923.         shr eax,16
  1924.         mov [esp+36],ax
  1925.         popad
  1926.         iretd
  1927. ;═════════════════════════════════════════════════════════════════════════════
  1928. ; all exceptions except 0dh. all are terminal, others are redirected.
  1929. cp_exc0:
  1930.         push eax
  1931.         mov ax,1000h
  1932.         jmp cp_irq
  1933. cp_exc1:
  1934.         push eax
  1935.         mov ax,1001h
  1936.         jmp cp_irq
  1937. cp_exc2:
  1938.         push eax
  1939.         mov ax,1002h
  1940.         jmp cp_irq
  1941. cp_exc3:
  1942.         push eax
  1943.         mov ax,1003h
  1944.         jmp cp_irq
  1945. cp_exc4:
  1946.         push eax
  1947.         mov ax,1004h
  1948.         jmp cp_irq
  1949. cp_exc5:
  1950.         push eax
  1951.         mov ax,1005h
  1952.         jmp cp_irq
  1953. cp_exc6:
  1954.         pushad
  1955.         mov al,6
  1956.         jmp short cp_exc
  1957. cp_exc7:
  1958.         push eax
  1959.         mov ax,1007h
  1960.         jmp cp_irq
  1961. cp_exc8:
  1962.         pushad
  1963.         mov al,8
  1964.         jmp short cp_exc
  1965. cp_exc9:
  1966.         pushad
  1967.         mov al,9
  1968.         jmp short cp_exc
  1969. cp_exca:
  1970.         pushad
  1971.         mov al,0ah
  1972.         jmp short cp_exc
  1973. cp_excb:
  1974.         pushad
  1975.         mov al,0bh
  1976.         jmp short cp_exc
  1977. cp_excc:
  1978.         pushad
  1979.         mov al,0ch
  1980.         jmp short cp_exc
  1981. cp_exce:
  1982.         pushad
  1983.         mov al,0eh
  1984.         jmp short cp_exc
  1985. cp_excf:
  1986.         pushad
  1987.         mov al,0ffh
  1988. ;-----------------------------------------------------------------------------
  1989. cp_exc:                                 ; main exception handler
  1990.         mov bx,10h
  1991.         mov ds,bx
  1992.         mov es,bx
  1993.         mov fs,bx
  1994.         mov gs,_selzero
  1995.         cld
  1996.         jmp _exit
  1997. ;═════════════════════════════════════════════════════════════════════════════
  1998. ; IRQ redirector between modes
  1999. cp_irq0:
  2000.         push eax
  2001.         mov ax,0008h
  2002.         jmp short cp_irq
  2003. cp_irq1:
  2004.         push eax
  2005.         mov ax,0109h
  2006.         jmp short cp_irq
  2007. cp_irq2:
  2008.         push eax
  2009.         mov ax,020ah
  2010.         jmp short cp_irq
  2011. cp_irq3:
  2012.         push eax
  2013.         mov ax,030bh
  2014.         jmp short cp_irq
  2015. cp_irq4:
  2016.         push eax
  2017.         mov ax,040ch
  2018.         jmp short cp_irq
  2019. cp_irq5:
  2020.         push eax
  2021.         mov ax,050dh
  2022.         jmp short cp_irq
  2023. cp_irq6:
  2024.         push eax
  2025.         mov ax,060eh
  2026.         jmp short cp_irq
  2027. cp_irq7:
  2028.         push eax
  2029.         mov ax,070fh
  2030.         jmp short cp_irq
  2031. cp_irq8:
  2032.         push eax
  2033.         mov ax,0870h
  2034.         jmp short cp_irq
  2035. cp_irq9:
  2036.         push eax
  2037.         mov ax,0971h
  2038.         jmp short cp_irq
  2039. cp_irqa:
  2040.         push eax
  2041.         mov ax,0a72h
  2042.         jmp short cp_irq
  2043. cp_irqb:
  2044.         push eax
  2045.         mov ax,0b73h
  2046.         jmp short cp_irq
  2047. cp_irqc:
  2048.         push eax
  2049.         mov ax,0c74h
  2050.         jmp short cp_irq
  2051. cp_irqd:
  2052.         push eax
  2053.         mov ax,0d75h
  2054.         jmp short cp_irq
  2055. cp_irqe:
  2056.         push eax
  2057.         mov ax,0e76h
  2058.         jmp short cp_irq
  2059. cp_irqf:
  2060.         push eax
  2061.         mov ax,0f77h
  2062. ;─────────────────────────────────────────────────────────────────────────────
  2063. cp_irq:                                 ; main IRQ handler thingy
  2064.         mov ss:cp_v86irqnum,al
  2065.         movzx eax,ah
  2066.         bt dword ptr ss:_irqmode,eax
  2067.         setc ss:cp_v86irqmode
  2068.         pop eax
  2069.         test byte ptr [esp+10],2
  2070.         jnz short cp_irqv86
  2071.         push ds es fs gs                ; real mode IRQ from pmode
  2072.         pushfd
  2073.         push cs
  2074.         push offset cp_irqpd
  2075.         pushad
  2076.         mov ax,10h
  2077.         mov ds,ax
  2078.         mov al,18h
  2079.         mov gs,ax
  2080.         mov al,cp_v86irqnum
  2081.         mov ebp,offset c_irqreal
  2082.         movzx ebx,cp_v86irqmode
  2083.         jmp cp_v86irqintr[ebx*4]
  2084. cp_irqpd:
  2085.         pop gs fs es ds
  2086.         iretd
  2087. ;─────────────────────────────────────────────────────────────────────────────
  2088. cp_irqv86:                              ; IRQ from V86, safe or norm redirect
  2089.         cmp cs:cp_v86irqmode,0
  2090.         jne short cp_irqv86s
  2091.         pushad                          ; normal IRQ redirection
  2092.         mov ax,18h
  2093.         mov ds,ax
  2094.         movzx edx,ss:cp_v86irqnum
  2095.         jmp cp_v86int
  2096. ;-----------------------------------------------------------------------------
  2097. cp_irqv86s:                             ; safe IRQ redirection
  2098.         pushfd
  2099.         push cs
  2100.         push offset cp_irqv86sd
  2101.         pushad
  2102.         mov ax,10h
  2103.         mov ds,ax
  2104.         mov al,18h
  2105.         mov gs,ax
  2106.         sub nextmodestack,STAKPMODE*16
  2107.         mov al,cp_v86irqnum
  2108.         mov ebp,offset c_irqreal
  2109.         jmp cp_v86irqintr[4]
  2110. ;-----------------------------------------------------------------------------
  2111. cp_irqv86sd:                            ; done with safe IRQ
  2112.         add nextmodestack,STAKPMODE*16
  2113.         iretd
  2114.  
  2115. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2116. ; Custom get IRQ handler offset
  2117. ; In:
  2118. ;   BL - IRQ num (0-0fh)
  2119. ; Out:
  2120. ;   EDX - offset of IRQ handler
  2121. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2122. cp_getirqvect:
  2123.         push ebx
  2124.         pushfd
  2125.         cli
  2126.         movzx ebx,bl
  2127.         mov bl,intslottbl[ebx]
  2128. ;       cmp bl,13
  2129. ;       je short cp_getirqvectf0
  2130.         lea ebx,[ebx*8]
  2131.         add ebx,cp_idt32ptr
  2132.         mov dx,[ebx+6]
  2133.         shl edx,16
  2134.         mov dx,[ebx]
  2135. cp_getirqvectd:
  2136.         popfd
  2137.         pop ebx
  2138.         ret
  2139. cp_getirqvectf0:
  2140. ;       mov edx,cp_int13vect
  2141. ;       jmp short cp_getirqvectd
  2142. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2143. ; Custom set IRQ handler offset
  2144. ; In:
  2145. ;   BL - IRQ num (0-0fh)
  2146. ;   EDX - offset of IRQ handler
  2147. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2148. cp_setirqvect:
  2149.         push ebx edx
  2150.         pushfd
  2151.         cli
  2152.         movzx ebx,bl
  2153.         mov bl,intslottbl[ebx]
  2154. ;       cmp bl,13
  2155. ;       je short cp_setirqvectf0
  2156.         lea ebx,[ebx*8]
  2157.         add ebx,cp_idt32ptr
  2158.         mov [ebx],dx
  2159.         shr edx,16
  2160.         mov [ebx+6],dx
  2161. cp_setirqvectd:
  2162.         popfd
  2163.         pop edx ebx
  2164.         ret
  2165. cp_setirqvectf0:
  2166. ;       mov cp_int13vect,edx
  2167. ;       jmp short cp_setirqvectd
  2168. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2169. ; Custom set the base addx for a selector
  2170. ; In:
  2171. ;   AX - selector
  2172. ;   EDX - linear base addx for selector
  2173. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2174. cp_setselector:
  2175. if SELECTORS ne 0
  2176.         push eax edx
  2177.         movzx eax,ax
  2178.         and edx,0ffffffh
  2179.         or edx,92000000h
  2180.         mov dword ptr gdt32[eax+2],edx
  2181.         mov dl,[esp+3]
  2182.         mov byte ptr gdt32[eax+7],dl
  2183.         pop edx eax
  2184. endif
  2185.         ret
  2186.  
  2187. code32  ends
  2188.  
  2189. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  2190. ; End of program (must be at end of program or you will suffer)
  2191. ;▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  2192. codeend segment para stack use32 'stack'
  2193. db STAKSIZE*16 dup(?)
  2194. codeend ends
  2195.         end     start16
  2196.  
  2197.